/*
	Copyright (c) 2011 Andrey O. Zbitnev (azbitnev@gmail.com)
	Licensed under the MIT License (LICENSE).

	$Id: ys.dialog.js 33 2012-10-05 06:18:48Z azbitnev@gmail.com $

	version: 0.9pa
*/

(function ($) {

	// private vars
	var queue = [], $shade = null

	// class dialog
	$.ys.dialog = { 

		shade: function (options) {

			var defaults = {
				background: '#fff',
				opacity: 0.8
			}

			var opts = $.extend(defaults, options)

			if (!$shade) {
				$shade = $('<div class="ys-dialog-shade"></div>').css({
					background: opts.background,
					position: 'fixed',
					left: '0',
					top: '0',
					width: '100%',
					height: '100%',
					opacity: opts.opacity,
					visibility: 'hidden'
				})
				$shade.appendTo('body')
			}

			return $shade
		},

		create: function (text, options, handler) {

			var defaults = {
				type: 'info', // alert | confirm | info | error | prompt | none
				buttons: [
					{ value: 'OK' }
				],
				inputs: [
					{ type: 'text' }
				],
				closable: true,
				//background: '#fff',
				//opacity: 0.8,
				setIcon: function ($dlg, icon) { $dlg.find('.icon').addClass(icon) },
				setText: function ($dlg, html) { $dlg.find('.text').html(html) },
				addButton: function ($dlg, $btn) { $dlg.find('.buttons').append($btn) },
				classes: '',
				template: function (opts) { return $(''
					+ '<div class="ys-dialog ' + opts.classes + ($.browser.msie && $.browser.version <= 9 ? ' ys-dialog-msie' : '') + '">'
						+ '<div class="top">'
							+ (opts.closable ? '<div class="ys-close"></div>' : '')
						+ '</div>'
						+ '<div class="middle">'
							+ '<div class="icon"></div>'
							+ '<div class="text"></div>'
							+ '<div class="clear"></div>'
						+ '</div>'
						+ '<div class="bottom">'
							+ '<div class="buttons"></div>'
							+ '<div class="clear"></div>'
						+ '</div>'
					+ '</div>'
					)
				},
				show: function ($msgbox, $shade) {
					$shade.css({ visibility: 'visible' })
					$msgbox.css({
						'margin-top': '-' + parseInt($msgbox.outerHeight() + parseInt(screen.height)).toString() + 'px',
						'margin-left': '-' + parseInt($msgbox.outerWidth() / 2).toString() + 'px',
						visibility: 'visible'
					})
					var $focus = $msgbox.find('.text:eq(0) > .input:eq(0) > input:eq(0)')
					if ($focus.length <= 0)
						$focus = $msgbox.find('button:eq(0)')
					$focus.focus()
					$msgbox.animate({
						'margin-top': '-' + parseInt($msgbox.outerHeight() / 2).toString() + 'px'
					}, 'fast', 'swing')
				},
				notReady: function ($msgbox) {
					var d = 20
					$msgbox.css({
						'margin-left': '-' + parseInt($msgbox.outerWidth() / 2 - d).toString() + 'px',
						visibility: 'visible'
					}).animate({
						'margin-left': '-' + parseInt($msgbox.outerWidth() / 2 + d).toString() + 'px'
					}, 'fast', 'swing').animate({
						'margin-left': '-' + parseInt($msgbox.outerWidth() / 2 - d).toString() + 'px'
					}, 'fast', 'swing').animate({
						'margin-left': '-' + parseInt($msgbox.outerWidth() / 2).toString() + 'px'
					}, 'fast', 'swing')
				},
				hide: function ($msgbox, $shade) {
					$msgbox.css({ visibility: 'hidden' })
					$shade.css({ visibility: 'hidden' })
				}
			}

			var buttonDefaults = {
				type: 'submit', // submit | cancel
				value: 'OK'
			}

			var inputDefaults = {
				type: 'text',
				label: '',
				value: '',
				required: false
			}

			var opts = $.extend(defaults, options)
			var shade = $.ys.dialog.shade(opts)

			var $tmpl = (typeof opts.template == 'function' ? opts.template(opts) : $(opts.template))
			$tmpl.data('ys-dialog-type', opts.type)
			opts.setIcon($tmpl, opts.type)
			if (opts.type == 'prompt') {
				$.each(opts.inputs, function () {
					var inp = $.extend(inputDefaults, this)
					text += (inp.label ? '<div class="label">' + inp.label + '</div>' : '')
						+ '<div class="input"><input type="' + inp.type + '" data-ys-dialog-required="' + (inp.required ? 'true' : 'false') + '" value="' + (inp.value.replace(/"/g, '&quot;')) + '"/></div>'
				})
			}
			opts.setText($tmpl, text)

			function buttonClickHandler() {
				var res = []
				var $t = queue.pop()
				var canceled = false
				var ready = true
				if ($tmpl.data('ys-dialog-type') == 'prompt') {
					var $empty = null
					$tmpl.find('.text > .input > input').each(function () {
						var $inp = $(this)
						var val = $inp.val()
						if (/^true$/i.test($inp.data('ys-dialog-required')) && val == '') {
							ready = false
							if (!$empty)
								$empty = $inp
						} else {
							res.push(val)
						}
					})
					if (/^cancel$/i.test($(this).data('ys-dialog-type'))) {
						ready = true
						canceled = true
					} else {
						if (ready == false && $empty)
							$empty.focus()
					}
				}
				if (ready) {
					opts.hide($tmpl, shade)
					if (!canceled) {
						if (handler) {
							res.unshift($(this).text())
							handler.apply(handler, res)
						}
					} else {
						handler.apply(handler, [ false ])
					}
					$tmpl.remove()
					if (queue.length >= 1)
						opts.show(queue[queue.length - 1], shade)
				} else {
					opts.notReady($tmpl)
				}
			}

			$.each(opts.buttons, function () {
				var btn = this
				if (btn instanceof String)
					btn = { 'value': btn }
				btn = $.extend(buttonDefaults, btn)
				var $btn = $('<button data-ys-dialog-type="' + btn.type + '"></button>').text(btn.value).click(buttonClickHandler)
				opts.addButton($tmpl, $btn)
			})

			$tmpl.css({ position: 'fixed', top: '50%', left: '50%', visibility: 'hidden' }).appendTo('body')

			$tmpl.find('.ys-close').data('ys-dialog-type', 'cancel').click(buttonClickHandler)

			$tmpl.find('input').each(function (i) {
				$(this).data('ys-dialog-input-index', i)
			}).keydown(function (evt) {
				if (evt.keyCode === 13) { // Enter/Return
					evt.preventDefault()
					evt.stopPropagation()
					var i = $(this).data('ys-dialog-input-index')
					var $next = $tmpl.find('input').eq(i + 1)
					if ($next.length > 0) {
						$next.focus()
					} else {
						$tmpl.find('button:eq(0)').click()
					}
					return false
				}
			})

			$tmpl.keydown(function (evt) {
				if (evt.keyCode === 27) { // Escape
					evt.preventDefault()
					evt.stopPropagation()
					$tmpl.find('.ys-close').click()
					return false
				}
			})

			queue.unshift($tmpl)
			if (queue.length == 1)
				opts.show(queue[0], shade)
		}
	}

})(jQuery);

